﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace OnlineMealOrdering.Common
{
    public class EncryptHelper
    {
        public static string EncryptUserPassword(string password)
        {
            byte[] passwordAndSaltBytes = System.Text.Encoding.UTF8.GetBytes("shifeixuan" + password + "xuziling");
            byte[] hashBytes = new System.Security.Cryptography.SHA256Managed().ComputeHash(passwordAndSaltBytes);
            byte[] disturbBytes = new byte[hashBytes.Length];
            byte disturb = (byte)56;
            for (int i = 0; i < hashBytes.Length; i++)
            {
                disturbBytes[i] = (byte)(hashBytes[i] & disturb);
            }
            string hashString = Convert.ToBase64String(disturbBytes);
            // you can also use ToHexString to convert byte[] to string     
            //string hashString = ToHexString(hashBytes); 
            return hashString;
        }

        UTF8Encoding encoding = new UTF8Encoding();
        private RijndaelManaged rijndaelManaged;
        private string key = ConfigurationManager.AppSettings["SecurityKey"];
        private string iv = ConfigurationManager.AppSettings["SecurityIV"];

        // 初始化加密类信息
        private RijndaelManaged CreateRijndaelManaged()
        {
            rijndaelManaged = new RijndaelManaged();
            rijndaelManaged.Padding = PaddingMode.PKCS7;
            rijndaelManaged.BlockSize = 128;
            rijndaelManaged.Mode = CipherMode.CBC;
            rijndaelManaged.Key = encoding.GetBytes(key);
            rijndaelManaged.IV = encoding.GetBytes(iv);
            return rijndaelManaged;
        }

        /// <summary>
        /// 对称加密方法
        /// </summary>
        /// <param name="source">待加密的串</param>
        /// <returns>经过加密的串</returns>
        public string Encrypt(string source)
        {
            string strOut = "";
            byte[] bytOut = new byte[] { };
            using (rijndaelManaged = this.CreateRijndaelManaged())
            {
                ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor();
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(source);
                        }
                    }
                    bytOut = msEncrypt.ToArray();
                }
            }
            for (int i = 0; i < bytOut.Length; i++)
            {
                //将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符
                strOut += bytOut[i].ToString("x2");
            }
            return strOut;
        }

        /// <summary>
        /// 对称解密方法
        /// </summary>
        /// <param name="source">待解密的串</param>
        /// <returns>经过解密的串</returns>
        public string Decrypt(string source)
        {
            string strOut = "";
            if (string.IsNullOrEmpty(source) || source.Length % 2 == 1)
            {
                return strOut;
            }
            byte[] bytIn = new byte[source.Length / 2];
            for (int i = 0; i < source.Length; i = i + 2)
            {
                bytIn[i / 2] = (byte)Convert.ToInt32(source.Substring(i, 2), 16);
            }
            using (rijndaelManaged = this.CreateRijndaelManaged())
            {
                ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor();
                using (MemoryStream msDecrypt = new MemoryStream(bytIn))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            strOut = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
            return strOut;
        }

        public static string GenPasswordSalt()
        {
            // random salt via GUID 
            string salt = Guid.NewGuid().ToString();

            // random salt via RNGCryptoServiceProvider
            //System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();     
            //byte[] saltBytes = new byte[36];     
            //rng.GetBytes(saltBytes);     
            //string salt = Convert.ToBase64String(saltBytes);     
            //string salt = ToHexString(saltBytes);  

            return salt;
        }
    }
}
